﻿#ifndef _MQTTSERVICE_H_
#define _MQTTSERVICE_H_

//#include <set>
//#include <map>
//#include <list>
#include <string>
#include "./mosquitto/include/mosquittopp.h"
#include <boost/thread/recursive_mutex.hpp>
#include "xxtea.h"

#ifdef _WIN32
#ifdef NDEBUG
#pragma comment(lib,"mosquittopp.lib")
#else
#pragma comment(lib,"mosquittoppd.lib")
#endif
#endif
typedef enum {
	SHADOW_GET = 0, SHADOW_UPDATE = 1, SHADOW_CTRL = 2,
}ShadowActions;


class CMQTTService;
typedef boost::shared_ptr<CMQTTService> cmqtt_service_ptr;

class IMqttEvent
{
public:
	virtual int OnConnect(CMQTTService *mq,std::string strid, int rc) = 0;
	virtual int OnDisconnect(CMQTTService *mq, std::string strid, int rc) = 0;
	virtual int OnMessage(CMQTTService *mq, std::string strid, ShadowActions actions, std::string payload) = 0;
	virtual int OnSubscribe(CMQTTService *mq, std::string strid, int mid, int qos_count, const int *granted_qos) = 0;
    virtual int OnUnsubscribe(CMQTTService *mq, std::string strid, int mid) = 0;
	virtual int OnPublish(CMQTTService *mq, std::string strid, int mid) = 0;
};
typedef boost::shared_ptr<IMqttEvent>mqtt_event_ptr;



typedef struct Mqttconfig{
   std::string strmqttid;
   std::string strkey;//用于数据加密
   std::string strmqtthost;
   std::string strusrname;
   std::string strusrpwd;
   int mqttport;
   //int keepalive;
   //int qos;
   //int retain;
} MQTTCONFIG;
class CMQTTService : public mosqpp::mosquittopp
{

public:
    CMQTTService(const MQTTCONFIG config, IMqttEvent* event);
    CMQTTService(IMqttEvent* event);
    virtual ~CMQTTService();
    int Start(const MQTTCONFIG config);
    void Stop();
    int disconnect();
	int reconnect();
	int reconnect_async();
    
	void on_connect(int rc);
	void on_disconnect(int rc);
	void on_message(const struct mosquitto_message *message);
	void on_subscribe(int mid, int qos_count, const int *granted_qos);
	void on_publish(int mid);
    void on_unsubscribe(int mid);
    
    int devSubscribe();
	int pushUpdateData(int payloadlen=0, const void *payload=NULL);
    int pushGetData();
    bool IsConnect(){return m_connect;}
private:
    int addJsonHeader(std::string & strdata, std::string strdevid ,ShadowActions action, std::string requestid = "");
    void addJsonTail(std::string & data, int version = 0);
    std::string getRequestId(int strlen = 16);
    std::string getUpdateJson(std::string & data, int version = 0, std::string requestid = "");
    std::string getGetJson(std::string requestid = "");
    ShadowActions GetActions(std::string straction);

private:
    MQTTCONFIG m_mqttconfig;
    IMqttEvent *m_event;
    std::string m_strsubtopic;
    std::string m_strpubtopic;
    bool m_connect;
    bool m_disonnect;//判断是否调用断开连接函数
    XXTEA_TYPE m_key[4]; //加密的key
};



#endif
